package cc.rengu.igas.channel.alipay.core.packswitch;


import cc.rengu.igas.channel.alipay.common.constant.AlipayParamConstant;
import cc.rengu.igas.channel.alipay.common.constant.AlipayTreeNodeConstant;
import cc.rengu.igas.channel.alipay.common.enums.RespCodeEnum;
import cc.rengu.igas.channel.alipay.core.realize.AlipaySignService;
import cc.rengu.igas.channel.alipay.core.realize.impl.AlipaySignServiceImpl;
import cc.rengu.jradp.packetswitch.IncomingPackSwitchImpl;
import cc.rengu.jradp.packetswitch.OutgoingPackSwitchImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.CertInfoMapper;
import cc.rengu.oltp.service.common.dao.DstChannelInfoMapper;
import cc.rengu.oltp.service.common.dao.SecPlanInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.CertInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.DstChannelInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SecPlanInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.CertInfo;
import cc.rengu.oltp.service.common.entity.DstChannelInfo;
import cc.rengu.oltp.service.common.entity.SecPlanInfo;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;

import java.net.URLDecoder;
import java.util.*;

public class NuccAlipayNoticePackSwitch implements IncomingPackSwitchImpl, OutgoingPackSwitchImpl {


    @Override
    public byte[] afterOutgoPackSwitch(byte[] arg0) throws Exception {
        XmlTreeUtil tree = new XmlTreeUtil();
        String respCode = tree.getXmlTreeStringValue("respCode");
        if ("00000000".equals(respCode) || "00".equals(respCode) || "SUCCESS".equals(respCode)) {
            return "SUCCESS".getBytes();
        } else {
            return "FAIL".getBytes();
        }
    }

    @Override
    public int beforeOutgoPackSwitch() throws Exception {
        return 0;
    }

    @Override
    public int afterInComPackSwitch() throws Exception {
        RgLogger rglog = RgLog.getLogger(this.getClass().getName());
        //赋值默认机构、渠道、交易细分
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.INST_ID, AppParamConstant.DEFAULT_INSTID);
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.MSG_SRC_ID, AlipayParamConstant.TUNL_ID_NUCCALIP);
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.BIZ_TYPE, AppParamConstant.DEFAULT_BIZ_TYPE);
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "T00SH102");

        String sign = xmlTreeUtil.getXmlTreeStringValue("sign");
        if (null == sign) {
            rglog.debug("无签域，不进行签名校验!");
            return 0;
        }

        /* 获取数字签名字符串 */
        String signBlock = xmlTreeUtil.getXmlTreeStringValue("signBlock");
        rglog.debug("加签Block:<{}>", signBlock);
        rglog.debug("sign:<{}>", sign);
        /* 获取通道配置信息 */
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        DstChannelInfoMapper dstChannelInfoMapper = new DstChannelInfoMapperImpl();
        DstChannelInfo dstChannelInfo = dstChannelInfoMapper.selectDstChannelInfoByPrimaryKey(instId, AlipayParamConstant.TUNL_ID_NUCCALIP);
        if (null == dstChannelInfo) {
            rglog.error("获取通道<{}>配置信息失败!", AlipayParamConstant.TUNL_ID_NUCCALIP);
            throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
        } else {
            if (AppParamConstant.NO.equals(dstChannelInfo.getDstChannelStatus())) {
                rglog.error("通道状态异常,status:<{}>", dstChannelInfo.getDstChannelStatus());
                throw new BizException(RespCodeEnum.CHANNEL_STATUS_UNNORMAL.getRespCode(), RespCodeEnum.CHANNEL_STATUS_UNNORMAL.getRespDesc());
            }
        }
        xmlTreeUtil.setXmlTreeObjectValue(AlipayTreeNodeConstant.DST_CHANNEL_INFO, dstChannelInfo);
        /* 根据通道安全计划获取安全计划 */
        SecPlanInfoMapper secPlanInfoMapper = new SecPlanInfoMapperImpl();
        List<SecPlanInfo> secPlanInfoList = secPlanInfoMapper.selectSecPlanInfoBySecPlanId(instId, dstChannelInfo.getSecPlanId());
        if (null != secPlanInfoList && !secPlanInfoList.isEmpty()) {
            xmlTreeUtil.setXmlTreeStringValue(AlipayTreeNodeConstant.SEC_PLAN_INFO_LIST, JSON.toJSONString(secPlanInfoList));
            /* 获取敏感信息加密证书 */
            Optional<SecPlanInfo> checkSignSecPlanOpt = secPlanInfoList.stream().filter(item -> item.getSecPlanType().equals(AlipayParamConstant.VERIFY_CERT_TYPE)).findFirst();
            if (checkSignSecPlanOpt.isPresent()) {
                CertInfoMapper certInfoMapper = new CertInfoMapperImpl();
                CertInfo certInfo = certInfoMapper.selectCertInfoByPrimaryKey(checkSignSecPlanOpt.get().getSecPlanId() + checkSignSecPlanOpt.get().getSecPlanType());
                if (null == certInfo) {
                    rglog.error("获取通道证书<{}>配置信息失败!", dstChannelInfo.getSecPlanId());
                    throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
                }
                AlipaySignService alipaySignService = new AlipaySignServiceImpl();
                /* 验证签名 */
                if (alipaySignService.verifySignString(sign, signBlock, certInfo)) {
                    rglog.info("签名验证成功!");
                    return 0;
                } else {
                    rglog.error("签名验证失败!");
                    return 0;
                }
            }
        }
        return -1;

    }

    @Override
    public byte[] beforeInComPackSwitch(byte[] arg0) throws Exception {
        RgLogger rglog = RgLog.getLogger(this.getClass().getName());
        String input;
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ArrayList<String> arrayList = new ArrayList<>();
        Map<String, String> msgMap = new HashMap<>();
        String signBlock = "";
        String charset;
        int i = 0;
        input = new String(arg0);
        if (input.contains("GBK") || input.contains("gbk")) {
            rglog.trace("GBK编码...");
            charset = "gbk";
        } else {
            rglog.trace("UTF-8编码...");
            charset = "utf-8";
        }
        String[] str = input.split("&", -1);
        for (i = 0; i < str.length; i++) {
            String[] str1 = str[i].split("=", -1);
            String str2 = URLDecoder.decode(str1[1], charset);
            xmlTreeUtil.setXmlTreeStringValue(str1[0], str2);
            msgMap.put(str1[0], str2);
            if (!"sign".equals(str1[0]) && !"sign_type".equals(str1[0])) {
                arrayList.add(str1[0] + "=" + str2 + "&");
            }
        }
        String[] strArray = arrayList.toArray(new String[arrayList.size()]);
        Arrays.sort(strArray);
        StringBuffer stringBuffer = new StringBuffer();
        for (i = 0; i < strArray.length; i++) {
            stringBuffer.append(strArray[i]);
        }
        signBlock = stringBuffer.substring(0, stringBuffer.length() - 1).toString();
        rglog.debug("signBlock=[{}]", signBlock);
        xmlTreeUtil.setXmlTreeStringValue("signBlock", signBlock);

        rglog.trace("msgMap:<{}>", JSON.toJSONString(msgMap));
        return JSON.toJSONString(msgMap).getBytes();
    }

}
